package com.ctsi.system.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ctsi.common.util.Search;
import com.ctsi.core.common.entity.LoginUser;
import com.ctsi.core.common.enums.StatusType;
import com.ctsi.core.common.util.$;
import com.ctsi.core.common.util.StringPool;
import com.ctsi.core.database.util.PageUtil;
import com.ctsi.core.web.enums.DataScopeTypeEnum;
import com.ctsi.system.entity.Org;
import com.ctsi.system.mapper.EmpMapper;
import com.ctsi.system.mapper.OrgMapper;
import com.ctsi.system.service.IOrgService;
import com.ctsi.system.vo.OrgResVO;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 系统组织机构表 服务实现类
 * </p>
 *
 * @author wang xiao xiang
 */
@Service
public class OrgServiceImpl extends ServiceImpl<OrgMapper, Org> implements IOrgService {

	@Resource
	private EmpMapper empMapper;

	@Override
	public IPage<Org> listPage(Org org, Search search) {
		boolean isPid = $.isNotEmpty(org.getPid());
		LambdaQueryWrapper<Org> queryWrapper = Wrappers.<Org>lambdaQuery()
				// 判断pid不为空，则查询
				.eq(isPid, Org::getPid, org.getPid())
				.or(isPid)
				.like(isPid, Org::getHierarchy, org.getPid())
				// 根据组织机构名称模糊查询
				.like($.isNotBlank(search.getKeyword()), Org::getName, search.getKeyword())
				// 根据sort进行正序排序
				.orderByAsc(Org::getSort);
		return this.baseMapper.selectPage(PageUtil.getPage(search), queryWrapper);
	}

	@Override
	public List<Long> getDataScopeListByDataScopeType(Integer dataScopeType, Long orgId) {
		List<Long> resultList = CollectionUtil.newArrayList();
		if (ObjectUtil.isEmpty(orgId)) {
			return CollectionUtil.newArrayList();
		}
		// 如果是范围类型是全部数据，则获取当前系统所有的组织架构id
		if (DataScopeTypeEnum.ALL.getCode().equals(dataScopeType)) {
			resultList = this.getOrgIdAll();
		}

		// 如果范围类型是本部门及以下部门，则查询本节点和子节点集合，包含本节点
		else if (DataScopeTypeEnum.DEPT_WITH_CHILD.getCode().equals(dataScopeType)) {
			resultList = this.getChildIdListWithSelfById(orgId);
		}

		// 如果数据范围是本部门，不含子节点，则直接返回本部门
		else if (DataScopeTypeEnum.DEPT.getCode().equals(dataScopeType)) {
			resultList.add(orgId);
		}
		return resultList;
	}

	/**
	 * 根据条件获取组织机构id集合
	 *
	 * @return 组织机构ID列表
	 */
	private List<Long> getOrgIdAll() {
		return this.list(Wrappers.<Org>lambdaQuery()
				.eq(Org::getStatus, StatusType.ENABLE.getCode()))
				.stream().map(Org::getId).collect(Collectors.toList());
	}

	/**
	 * 根据节点id获取所有子节点id集合，包含自己
	 *
	 * @param id 父ID
	 * @return ID集合列表
	 */
	@Override
	public List<Long> getChildIdListWithSelfById(Long id) {
		List<Long> childIdListById = this.getChildIdListById(id);
		List<Long> resultList = CollectionUtil.newArrayList(childIdListById);
		resultList.add(id);
		return resultList;
	}

	/**
	 * 根据节点id获取所有子节点id集合
	 *
	 * @param id PID
	 * @return ID集合
	 */
	private List<Long> getChildIdListById(Long id) {

		return this.list(Wrappers.<Org>query().lambda()
				.like(Org::getHierarchy, StringPool.LEFT_SQ_BRACKET + id + StringPool.RIGHT_SQ_BRACKET))
				.stream().map(Org::getId).collect(Collectors.toList());

	}

	@Override
	public List<OrgResVO> tree(LoginUser user, Search search) {

		LambdaQueryWrapper<Org> queryWrapper = Wrappers.lambdaQuery();

		// 统一封装数据范围的方法
		queryWrapper = getDataScopeQuery(queryWrapper, user, search);
		if ($.isEmpty(queryWrapper)) {
			return CollectionUtil.newArrayList();
		}
		queryWrapper.eq(Org::getStatus, StatusType.ENABLE.getCode())
				.orderByAsc(Org::getSort);

		return this.list(queryWrapper).stream().map(org -> {
			OrgResVO orgRes = new OrgResVO();
			orgRes.setId(org.getId());
			orgRes.setParentId(org.getPid());
			orgRes.setTitle(org.getName());
			orgRes.setValue($.toStr(org.getId()));
			orgRes.setWeight(org.getSort());
			return orgRes;
		}).collect(Collectors.toList());
	}

	@Override
	public List<Org> list(LoginUser user, Org org, Search search) {
		LambdaQueryWrapper<Org> queryWrapper = Wrappers.<Org>lambdaQuery()
				//根据父机构id查询
				.eq($.isNotEmpty(org.getPid()), Org::getPid, org.getPid());

		// 统一封装数据范围的方法
		queryWrapper = getDataScopeQuery(queryWrapper, user, search);
		if ($.isEmpty(queryWrapper)) {
			return CollectionUtil.newArrayList();
		}

		queryWrapper.eq(Org::getStatus, StatusType.ENABLE.getCode());
		//根据排序升序排列，序号越小越在前
		queryWrapper.orderByAsc(Org::getSort);
		return this.list(queryWrapper);
	}

	/**
	 * 根据节点id获取所有父节点id集合，不包含自己
	 *
	 * @param id 组织机构ID
	 * @return 父节点ID列表
	 */
//	private List<Long> getPidByHierarchy(Long id) {
//		Org org = this.getById(id);
//		String hierarchy = org.getHierarchy();
//		// 移除左右括号
//		String hierarchyLeft = StrUtil.removeAll(hierarchy, StringPool.LEFT_SQ_BRACKET);
//		String hierarchyResult = StrUtil.removeAll(hierarchyLeft, StringPool.RIGHT_SQ_BRACKET);
//		return $.toLongList(StringPool.COMMA, hierarchyResult);
//	}

	/**
	 * 封装查询数据范围
	 *
	 * @param user   用户信息
	 * @param search 搜索信息
	 * @return 查询对象
	 */
	private LambdaQueryWrapper<Org> getDataScopeQuery(LambdaQueryWrapper<Org> queryWrapper, LoginUser user, Search search) {
		//如果是超级管理员则获取所有组织机构，否则只获取其数据范围的机构数据
//		if (!$.equals(AdminTypeEnum.SUPER_ADMIN.getCode(), user.getAdminType())) {
//			List<Long> dataScope = search.getDataScope();
//			if ($.isEmpty(dataScope)) {
//				return null;
//			} else {
//				Set<Long> dataScopeSet = CollectionUtil.newHashSet(dataScope);
//				dataScope.forEach(orgId -> {
//					//此处获取所有的上级节点，放入set，用于构造完整树
//					List<Long> parentAndChildIdListWithSelf = this.getPidByHierarchy(orgId);
//					dataScopeSet.addAll(parentAndChildIdListWithSelf);
//				});
//				queryWrapper.in(Org::getId, dataScopeSet);
//			}
//		}
		return queryWrapper;
	}

	@Override
	public boolean setOrg(Org org) {
		fillHierarchy(org, org.getPid());
		return this.saveOrUpdate(org);
	}

	private void fillHierarchy(Org org, Long pid) {
		if ($.equals(0L, pid)) {
			org.setHierarchy(StringPool.LEFT_SQ_BRACKET + 0 + StringPool.RIGHT_SQ_BRACKET
					+ StringPool.COMMA);
		} else {
			Org parentOrg = this.getById(pid);
			org.setHierarchy(parentOrg.getHierarchy() + StringPool.LEFT_SQ_BRACKET + pid + StringPool.RIGHT_SQ_BRACKET
					+ StringPool.COMMA);
		}
	}

	@Override
	public boolean checkOrgExistUser(Long orgId) {
		int result = empMapper.checkOrgExistUser(orgId);
		return result > 0;
	}
}
